home *** CD-ROM | disk | FTP | other *** search
/ Nebula 1 / Nebula One.iso / Graphics / Viewers / aa_m68k_Intel_Only / ToyViewer1.2 / Source / gifbmap.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-11-12  |  4.0 KB  |  164 lines

  1. /*
  2.     gifbmap.h
  3.  
  4.     gifheader.c, gifbmap.c, and gif.h are based on "giftoppm"
  5.     of David Koblas.
  6.     They are modified by T. Ogihara. (1995)
  7. */
  8.  
  9. /* +-------------------------------------------------------------------+ */
  10. /* | Copyright 1990, David Koblas.                                     | */
  11. /* |   Permission to use, copy, modify, and distribute this software   | */
  12. /* |   and its documentation for any purpose and without fee is hereby | */
  13. /* |   granted, provided that the above copyright notice appear in all | */
  14. /* |   copies and that both that copyright notice and this permission  | */
  15. /* |   notice appear in supporting documentation.  This software is    | */
  16. /* |   provided "as is" without express or implied warranty.           | */
  17. /* +-------------------------------------------------------------------+ */
  18.  
  19. #include  "gif.h"
  20. #include  "strfunc.h"
  21.  
  22. char    *Comment;
  23.  
  24. static int ReadColorMap(FILE *, gifHeader *gh);
  25. static int DoExtension(FILE *);
  26. static int ReadImage(FILE *, const gifHeader *, int, BOOL, unsigned char **);
  27.  
  28. int gifGetImage(FILE *fp, gifHeader *gh, int *bits, unsigned char **planes)
  29. {
  30.     int    c, rt, bitp = 8;
  31.     BOOL    isgray = NO;
  32.  
  33.     Comment = NULL;
  34.     if (gh->colormap) {    /* Global Colormap */
  35.         if ((bitp = ReadColorMap(fp, gh)) == 0)
  36.             return Err_FORMAT;
  37.         isgray = isGray(gh->palette, gh->colors);
  38.     }
  39.  
  40.     while ((c = getc(fp)) != ',' ) {    /* start character */
  41.         if (c == EOF || c == ';')    /* GIF terminator */
  42.             return Err_SHORT;
  43.         if (c == '!') {     /* Extension */
  44.             if (DoExtension(fp) < 0)
  45.                 return Err_ILLG;
  46.         }
  47.         /* other chars are illegal... ignore */
  48.     }
  49.     if (Comment)
  50.         gh->memo = Comment, Comment = NULL;
  51.  
  52.     (void)get_long(fp); /* skip 4 bytes */
  53.     gh->width = get_short(fp);
  54.     gh->height = get_short(fp);
  55.     c = getc(fp);
  56.     gh->interlace = BitSet(c, INTERLACE);
  57.     if (BitSet(c, LOCALCOLORMAP)) { /* Use Local Color Map */
  58.         gh->colors = 2 << (c & 0x07);
  59.         if ((bitp = ReadColorMap(fp, gh)) == 0)
  60.             return Err_FORMAT;
  61.         isgray = isGray(gh->palette, gh->colors);
  62.     }
  63.     /* Initialize the Compression routines */
  64.     if (initGifLZW(fp) == EOF)
  65.         return Err_SHORT;
  66.     *bits = bitp;
  67.     rt = ReadImage(fp, gh, bitp, isgray, planes);
  68.     if (isgray || bitp == 1) planes[1] = NULL;
  69.     return rt;
  70. }
  71.  
  72. static int
  73. ReadColorMap(FILE *fd, gifHeader *gh)
  74. {
  75.     int i, number;
  76.     paltype *pal;
  77.     unsigned char    *p;
  78.  
  79.     number = gh->colors;
  80.     if (gh->palette) {
  81.         free((void *)gh->palette);
  82.         gh->palette = NULL;
  83.     }
  84.     if ((pal = (paltype *)malloc(sizeof(paltype) * number)) == NULL)
  85.         return 0;
  86.     for (i = 0; i < number; ++i) {
  87.         p = pal[i];
  88.         p[RED] = getc(fd);
  89.         p[GREEN] = getc(fd);
  90.         p[BLUE] = getc(fd);
  91.         if (feof(fd)) {
  92.             free((void *)pal);
  93.             return 0;
  94.         }
  95.     }
  96.     gh->palette = pal;
  97.     return howManyBits(gh->palette, number);
  98. }
  99.  
  100. static int
  101. DoExtension(FILE *fd)
  102. {
  103.     int cc;
  104.     unsigned char    buf[256];
  105.  
  106.     switch (cc = getc(fd)) {
  107.     case 0x01:        /* Plain Text Extension */
  108.     case 0xff:        /* Application Extension */
  109.     case 0xf9:        /* Graphic Control Extension */
  110.         break;
  111.     case 0xfe:        /* Comment Extension */
  112.         while (GetDataBlock(fd, buf) != 0) {
  113.             if (Comment == NULL)
  114.             Comment = (unsigned char *)str_dup(buf);
  115.         }
  116.         return cc;
  117.     default:
  118.         return -1;    /* ERROR */
  119.     }
  120.     while (GetDataBlock(fd, buf) != 0)
  121.         ;
  122.     return cc;
  123. }
  124.  
  125. static int
  126. ReadImage(FILE *fd, const gifHeader *gh, int bitp, BOOL isgray,
  127.     unsigned char **planes)
  128. {
  129.     int    xpos, ypos, xbyte, pass, err;
  130.     long    wd;
  131.     unsigned char    *map[5];
  132.     unsigned char    buffer[MAXWidth];
  133.  
  134.     err = allocImage(planes, gh->width, gh->height, bitp, isgray);
  135.     if (err)
  136.         return err;
  137.     pass = 0;
  138.     xbyte = byte_length(bitp, gh->width);
  139.  
  140.     for (ypos = 0; ; ) {
  141.         for (xpos = 0; xpos < gh->width; xpos++)
  142.             buffer[xpos] = LWZReadByte(fd);
  143.         map[0] = planes[0] + (wd = xbyte * ypos);
  144.         if (!isgray) {
  145.             map[1] = planes[1] + wd;
  146.             map[2] = planes[2] + wd;
  147.         }
  148.         expandImage(map,
  149.             buffer, gh->palette, bitp, gh->width, isgray);
  150.         if (gh->interlace) {
  151.             ypos += pass ? (0x10 >> pass) : 0x08;
  152.             if (ypos >= gh->height) {
  153.                 if (++pass > 3)
  154.                     break;
  155.                 ypos = 8 >> pass;
  156.             }
  157.         }else {
  158.             if (++ypos >= gh->height)
  159.                 break;
  160.         }
  161.     }
  162.     return 0;
  163. }
  164.